#include "maplay.h"
#include "player.h"

BOOL  Initialized = FALSE;
TCHAR PlugInPath[MAX_PATH];
BYTE  ChannelVolume;
DWORD Pitch, Rate;
int   ID3Encoding = CP_ACP;

int   Instances = 0;

// Buffer data for Reader
extern LONGLONG m_blocksize;
extern int      m_maxBlocks;
extern int      m_minBlocks;


#if defined(MAPLAY_EXPORTS) && !defined(_WIN32_WCE)
BOOL __declspec(dllexport) APIENTRY DllMain( HANDLE hModule, 
                                            DWORD  ul_reason_for_call, 
                                            LPVOID lpReserved
                                            )
{
  return TRUE;
}
#endif

// Some Avian Play Registry Stuff
void GetPluginPathFromRegistry(TCHAR *path, int length)
{
  HKEY hk;
  DWORD disp = 0;
  DWORD maxBytes = 0;

  RegCreateKeyEx(HKEY_CURRENT_USER, _T("Software\\Avian Waves\\Avian Play\\Audio Engine"), 0, _T(""), 0, 0, NULL, &hk, &disp);
  if (hk != NULL)
  {
    maxBytes = length * sizeof(TCHAR);
    RegQueryValueEx(hk, _T("inPluginPath"), 0, NULL, (LPBYTE) path, &maxBytes);
    RegCloseKey(hk);
  }
}


void WINAPI MAP_SetPlugInPath(LPCTSTR); //Avian Play prototype required (below)
HANDLE WINAPI MAP_Initialize()
{
  // ADDED FOR AVIAN PLAY
  TCHAR szPluginPathAP[MAX_PATH];
  GetPluginPathFromRegistry(szPluginPathAP, MAX_PATH-1);
  MAP_SetPlugInPath(szPluginPathAP);

  TCHAR szModule[MAX_PATH];
  GetModuleFileName(NULL, szModule, MAX_PATH);
  LPTSTR p = _tcsrchr(szModule, _T('\\'));
  if (p) *p = NULL;
  if ( Initialized == FALSE )
  {
    Initialized = TRUE;
    //	   	wsprintf(PlugInPath, _T("%s\\PlugIns"), szModule);
    ChannelVolume = 255;
    Pitch = 0x00010000;
    Rate  = 0x00010000;
  }

  Instances++;
  CPlayer* pPlayer = new CPlayer();
  return pPlayer;
}

void WINAPI MAP_Uninitialize(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  delete pPlayer;
  Instances--;
}

BOOL WINAPI MAP_Open(HANDLE hLib, LPCTSTR pszFile)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->OpenFile(pszFile);
}

void WINAPI MAP_Close(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->Close();
}

BOOL WINAPI MAP_Play(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->Play();
}

void WINAPI MAP_Stop(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->Stop();
}

void WINAPI MAP_Pause(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->Pause();
}

// Now in seconds, not milliseconds
BOOL WINAPI MAP_Ff(HANDLE hLib, long lSkip)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->Ff(lSkip * 1000);
}

// Now in seconds, not milliseconds
BOOL WINAPI MAP_Rew(HANDLE hLib, long lSkip)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->Rew(lSkip * 1000);
}

// Now in seconds, not milliseconds
BOOL WINAPI MAP_Seek(HANDLE hLib, long lTime)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->Seek(lTime * 1000);
}

// Now in seconds, not milliseconds
long WINAPI MAP_GetDuration(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  long ret = pPlayer->GetDuration();
  if (ret > 0 && ret < 1000) 
  {
    return 1;
  }
  else
  {
    return ret / 1000;
  }
}

BOOL WINAPI MAP_IsValidStream(HANDLE hLib, LPCTSTR pszFile)
{
  CPlayer* pPlayer = (CPlayer*) hLib;

  if (IsValidFile(pszFile))
    return TRUE;

  if (pPlayer->OvIsValidFile(pszFile))
    return TRUE;

  if (pPlayer->WavIsValidFile(pszFile))
    return TRUE;

  if (pPlayer->PlugInIsValidFile(pszFile))
    return TRUE;

  return FALSE;
}

void WINAPI MAP_SetMessageWindow(HANDLE hLib, HWND hwndMessage)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->SetMessageWindow(hwndMessage);
}

void WINAPI MAP_SetCallbackFunction( HANDLE hLib, void(*callback)(void *,ULONG), void *param )
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->SetCallbackFunction(callback,param);
}

// Now in seconds, not milliseconds
long WINAPI MAP_GetCurrent(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->GetCurrent() / 1000;
}

void WINAPI MAP_SetEqualizer(HANDLE hLib, EQUALIZER* value)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->SetEqualizer(value);
}
void WINAPI MAP_GetEqualizer(HANDLE hLib, EQUALIZER* value)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->GetEqualizer(value);
}

void WINAPI MAP_SetEffect(HANDLE hLib, int nEffect, EFFECT* value)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->SetEffect(nEffect, value);
}

void WINAPI MAP_GetEffect(HANDLE hLib, int nEffect, EFFECT* value)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->GetEffect(nEffect, value);
}

void WINAPI MAP_SetBassBoostLevel(HANDLE hLib, int nLevel)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->SetBassBoostLevel(nLevel);
}

int WINAPI MAP_GetBassBoostLevel(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->GetBassBoostLevel();
}

void WINAPI MAP_GetFileInfo(HANDLE hLib, MAP_INFORMATION* pInfo)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->GetFileInformation(pInfo);
}

BOOL WINAPI MAP_GetId3Tag(HANDLE hLib, ID3TAGV1* pTag)
{
  //CPlayer* pPlayer = (CPlayer*) hLib;
  //return pPlayer->GetId3Tag(pTag);
  return FALSE;
}

BOOL WINAPI MAP_SetId3Tag(HANDLE hLib, ID3TAGV1* pTag)
{
  //CPlayer* pPlayer = (CPlayer*) hLib;
  //return pPlayer->SetId3Tag(pTag);
  return FALSE;
}

void WINAPI MAP_GetGenreString(HANDLE hLib, int nGenre, LPTSTR pszGenre)
{
  if (nGenre >= 0 && nGenre <= 147)
    _tcscpy(pszGenre, genre_strings[nGenre]);
}

BOOL WINAPI MAP_GetId3TagFile(HANDLE hLib, LPCTSTR pszFile, ID3TAGV1* pTag)
{
  //CPlayer* pPlayer = (CPlayer*) hLib;

  //if ( pPlayer->m_Cover != NULL ) free(pPlayer->m_Cover);
  //pPlayer->m_Cover = NULL;
  //pPlayer->m_CoverSize = 0;
  //pPlayer->m_CoverType = 0;

  //if (pPlayer->PlugInGetId3TagFile(pszFile, pTag))
  //  return TRUE;

  //if (pPlayer->OvGetId3TagFile(pszFile, pTag))
  //  return TRUE;

  //if (!IsValidFile(pszFile))
  //  return FALSE;

  //return GetId3Tag(pszFile, pTag, pPlayer->m_Cover, &pPlayer->m_CoverSize, &pPlayer->m_CoverType );
  return FALSE;
}

void* WINAPI MAP_GetId3Cover(HANDLE hLib, UINT *size, int *type)
{
  //CPlayer* pPlayer = (CPlayer*) hLib;
  //*size = pPlayer->m_CoverSize;
  //*type = pPlayer->m_CoverType;
  //return pPlayer->m_Cover;
  return NULL;
}

BOOL WINAPI MAP_SetId3TagFile(LPCTSTR pszFile, ID3TAGV1* pTag)
{
  //return SetId3Tag(pszFile, pTag);
  return NULL;
}

MAP_STATUS WINAPI MAP_GetStatus(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->GetStatus();
}

BOOL WINAPI MAP_SetOptions(HANDLE hLib, MAP_OPTIONS* pOptions)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->SetOptions(pOptions);
}

void WINAPI MAP_GetOptions(HANDLE hLib, MAP_OPTIONS* pOptions)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->GetOptions(pOptions);
}

BOOL WINAPI MAP_GetScanPeek(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->GetScanPeek();
}

void WINAPI MAP_SetScanPeek(HANDLE hLib, BOOL fScan)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->SetScanPeek(fScan);
}

void WINAPI MAP_AudioDeviceClose(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->AudioDeviceClose();
}

void WINAPI MAP_GetBufferInfo(HANDLE hLib, DWORD* pcbTotalAudio, DWORD* pcbBufferedAudio,
                              DWORD* pcbTotalStream, DWORD* pcbBufferedStream)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->GetBufferInfo(pcbTotalAudio, pcbBufferedAudio, pcbTotalStream, pcbBufferedStream);
}

// for streaming
BOOL WINAPI MAP_OpenURL(HANDLE hLib, LPCTSTR pszURL)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->OpenURL(pszURL);
}

BOOL WINAPI MAP_GetStreamInfo(HANDLE hLib, LPTSTR pszName, LPTSTR pszGenre, LPTSTR pszURL)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->GetStreamInfo(pszName, pszGenre, pszURL);
}

BOOL WINAPI MAP_GetStreamTitle(HANDLE hLib, LPTSTR pszTitle)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->GetStreamTitle(pszTitle);
}

BOOL WINAPI MAP_SetStreamingOptions(HANDLE hLib, MAP_STREAMING_OPTIONS* pOptions)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->SetStreamingOptions(pOptions);
}

void WINAPI MAP_GetStreamingOptions(HANDLE hLib, MAP_STREAMING_OPTIONS* pOptions)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  pPlayer->GetStreamingOptions(pOptions);
}

MAP_STREAMING_STATUS WINAPI MAP_GetStreamingStatus(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->GetStreamingStatus();
}

int WINAPI MAP_GetStreamingBufferingCount(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->GetStreamingBufferingCount();
}

int WINAPI MAP_GetDecoderPlugInCount(HANDLE hLib)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->PlugInGetCount();
}

MAP_DEC_PLUGIN* WINAPI MAP_GetDecoderPlugIn(HANDLE hLib, int nIndex)
{
  CPlayer* pPlayer = (CPlayer*) hLib;
  return pPlayer->PlugInGetInterface(nIndex);
}

void WINAPI MAP_SetPlugInPath(LPCTSTR path)
{
  wcscpy( PlugInPath, path );
}

void WINAPI MAP_SetChannelVolume(HANDLE hLib, BYTE volume)
{
  ChannelVolume = volume;
  if ( hLib != NULL )
  {
    CPlayer* pPlayer = (CPlayer*) hLib;
    pPlayer->UpdateChannelVolume();
  }
}

void WINAPI MAP_SetPitch(HANDLE hLib, DWORD pitch)
{
  Pitch = pitch;
  if ( hLib != NULL )
  {
    CPlayer* pPlayer = (CPlayer*) hLib;
    pPlayer->UpdatePitch();
  }
}

void WINAPI MAP_SetPlaybackRate(HANDLE hLib, DWORD rate)
{
  Rate = rate;
  if ( hLib != NULL )
  {
    CPlayer* pPlayer = (CPlayer*) hLib;
    pPlayer->UpdateRate();
  }
}

void WINAPI MAP_SetPrebuffer(LONGLONG blocksize, int minBlocks, int maxBlocks)
{
  m_blocksize = blocksize;
  m_maxBlocks = maxBlocks;
  m_minBlocks = minBlocks;
}

void WINAPI MAP_SetID3DefaultEncoding( int encoding )
{
  //ID3Encoding = encoding;
}
